home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
newsgrp
/
group01b.txt
/
000055_icon-group-sender_Thu Mar 8 08:01:52 2001.msg
< prev
next >
Wrap
Internet Message Format
|
2002-01-03
|
4KB
Return-Path: <icon-group-sender>
Received: (from root@localhost)
by baskerville.CS.Arizona.EDU (8.11.1/8.11.1) id f28F1mo23598
for icon-group-addresses; Thu, 8 Mar 2001 08:01:48 -0700 (MST)
Message-Id: <200103081501.f28F1mo23598@baskerville.CS.Arizona.EDU>
Date: Wed, 07 Mar 2001 20:40:02 -0600
From: Viktors Berstis <viktors@berstis.com>
X-Accept-Language: en
To: Icon-group <icon-group@cs.arizona.edu>, snobol4@mercury.dsu.edu
Subject: Re: New Scientist puzzle
Errors-To: icon-group-errors@cs.arizona.edu
Status: RO
Content-Length: 2966
OK, I could no longer resist either. Here is my solution in old
fashioned SNOBOL4:
d = LEN(1); DEFINE('c(x)'); &FULLSCAN = 1; t = TABLE(); i = 32
a j = 32
b ((i * i) ' ' (j * j))
+ ((d $ V d $ I d $ E d $ R) . vier ' ' (d $ N *E d $ U *N) . neun
*c(1023456789)) . z :F(x)
a = a '=' z '.'
r a '=' (vier ' ' t<'v' vier> | t<'n' neun> ' ' neun) '.' = :S(r)
t<'n' neun> = LEN(4)
t<'v' vier> = LEN(4)
x j = j + 1 LT(j,99) :S(b)
i = i + 1 LT(i,99) :S(a)
OUTPUT = 'Answer' a :(END)
c x ANY(N E U V I R) = :S(c)
EQ(SIZE(x),4) :S(RETURN)F(FRETURN)
END
Also, here is a more general version for any two words, which don't need
to be the same length along
with comments (the above program can be derived from this one):
* Specify two words w1 and w2 which are both squares - need not be the
same length
w1 = 'VIER'; w2 = 'NEUN'
* Another puzzle:
* w1 = 'FIVE'; w2 = 'NINE'
* Shorthand for LEN(1)
dg = LEN(1)
* Turn length heuristic off for pattern matching
&FULLSCAN = 1
* Table to keep track of unique solutions
tb = TABLE()
* Define the functions used
DEFINE('c(xx)')
DEFINE('bldpat(wd)')
* Compute low and high limits of square roots to index thru for each
word (funny char should be hat:)
lo1 = CONVERT(('1' DUPL('0',SIZE(w1) - 1)) ^ 0.5 + 1,'INTEGER')
hi1 = CONVERT(DUPL('9',SIZE(w1)) ^ 0.5,'INTEGER')
lo2 = CONVERT(('1' DUPL('0',SIZE(w2) - 1)) ^ 0.5 + 1,'INTEGER')
hi2 = CONVERT(DUPL('9',SIZE(w2)) ^ 0.5,'INTEGER')
* Build checking patterns for both words
p1 = EVAL(bldpat(w1))
p2 = EVAL(bldpat(w2))
* Start of two nested loops
j1 = lo1
a j2 = lo2
* Test a pair of squares
b ((j1 * j1) ' ' (j2 * j2)) (p1 . vier ' ' p2 . neun
*c(1023456789)) . zz :F(x)
* Now need to test to see if solution unique
ans = ans '=' zz '.'
* Remove prior candidates that use the same number for one word or the
other
r ans '=' (vier ' ' tb<'v' vier> | tb<'n' neun> ' ' neun) '.' =
:S(r)
* Remember numbers encountered as candidates
tb<'v' vier> = LEN(SIZE(w2))
tb<'n' neun> = LEN(SIZE(w1))
* Next iterations
x j2 = j2 + 1 LT(j2,hi2) :S(b)
j1 = j1 + 1 LT(j1,hi1) :S(a)
* Print answer(s) if any
OUTPUT = 'Answer' ans :(END)
* Function to check that two letters didn't get assigned to the same
digit
c xx ANY(EVAL(cc)) = :S(c)
* xx contains the digits not assigned to the letters, following checks
count:
EQ(SIZE(xx),10 - SIZE(seen)) :S(RETURN)F(FRETURN)
* Function to build test pattern for word wd
bldpat wd dg . let = :F(RETURN)
seen let :f(new)
bldpat = bldpat '*' let ' ' :(bldpat)
* Remember letters we have already seen (matched)
new seen = seen let
* cc will form argument for ANY in c function
cc = cc let ' '
bldpat = bldpat 'dg $ ' let ' ' :(bldpat)
END
-Viktors